home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
kms20src.lha
/
KMSS
/
serverrexx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-07
|
33KB
|
1,163 lines
/**********************************
* KMS *
**********************************
* ©1992 by BlackMagic Software *
**********************************
* *
**********************************/
#include <KMS/KMS.h>
#include <KMS/KMS_rexx.h>
#include <KMS/KMS_devlib.h>
Prototype VOID KMSRexxDisp(struct RexxMsg *, struct rexxCommandList *, STRPTR);
Prototype VOID RexxErr(UWORD);
Prototype VOID RexxOK(STRPTR, STRPTR);
Prototype VOID Rexx_GETKMSGC(struct RexxMsg *, LONG []);
Prototype VOID Rexx_SHUTDOWN(struct RexxMsg *, LONG []);
Prototype VOID Rexx_LOCKPORT(struct RexxMsg *, LONG []);
Prototype VOID Rexx_UNLOCKPORT(struct RexxMsg *, LONG []);
Prototype VOID Rexx_SAVESYS(struct RexxMsg *, LONG []);
Prototype VOID Rexx_LOGENTRY(struct RexxMsg *, LONG []);
Prototype VOID Rexx_EXPIRE(struct RexxMsg *, LONG []);
Prototype VOID Rexx_REFRESH(struct RexxMsg *, LONG []);
Prototype VOID SendPortCmd(STRPTR);
Prototype VOID RexxCmdParse(STRPTR, UBYTE *, STRPTR *);
Prototype BOOL CheckStack(VOID);
Prototype struct LocalConfig *GetKMSLC(struct RexxMsg *);
Prototype struct AreaNode *AreaSearch(STRPTR);
Prototype VOID TakeMSem(BOOL);
Prototype VOID DropMSem(VOID);
Prototype VOID TakeASem(BOOL);
Prototype VOID DropASem(VOID);
extern LONG SetMode(BPTR, LONG);
extern LONG IsInteractive(BPTR);
extern VOID KPrintF(APTR, ...);
/***********************************
* Globale Variable *
***********************************/
extern struct KMSBase *KMSBase;
extern ULONG RexxSignal;
extern UMSAccount SysUMSAccount;
extern UBYTE ShutDown;
struct LocalConfig *KMS_LC = NULL;
/* Liste implementierter Kommandos (lower case!) */
struct rexxCommandList RCL[] =
{
{"getkmsgc", (APTR)&Rexx_GETKMSGC, ""},
{"shutdown", (APTR)&Rexx_SHUTDOWN, "DELAY/K/N,UMS/S"},
{"lockport", (APTR)&Rexx_LOCKPORT, "DELAY/K/N"},
{"unlockport", (APTR)&Rexx_UNLOCKPORT, ""},
{"savesys", (APTR)&Rexx_SAVESYS, ""},
{"logentry", (APTR)&Rexx_LOGENTRY, "TEXT/F"},
{"expire", (APTR)&Rexx_EXPIRE, "QUIET/S,RESET/S,UNLISTED/S"},
{"refresh", (APTR)&Rexx_REFRESH, "SYSTEM/S,ALL/S,UMSGLOBAL/S"},
{NULL, NULL, NULL}
};
#define ERR_INVALID_PARAMS 1
#define ERR_TOO_MANY_PARAMS 2
#define ERR_ALREADY_LOCKED 3
#define ERR_NOT_LOCKED 4
#define ERR_TOO_FEW_PARAMS 5
#define ERR_NO_LOGIN 6
#define ERR_USER_ACTIVE 7
#define ERR_INVALID_PASSWORD 8
#define ERR_NO_SUCH_USER 9
#define ERR_NO_SUCH_UMS_USER 10
#define ERR_NO_MSG_READ 11
#define ERR_UMS_READ_ERROR 12
#define ERR_SHUTDOWN 13
#define ERR_NO_VARNAME 14
#define ERR_VARNAME_TOO_LONG 15
#define ERR_TIMEOUT 16
#define ERR_OUT_OF_MEMORY 17
#define ERR_ONLY_CURRENT_PWD 18
#define ERR_FILE_NOT_FOUND 19
STRPTR RexxErrStr[20] =
{
"",
" 1: Invalid parameters",
" 2: Too many parameters",
" 3: Port already locked",
" 4: Port is not locked",
" 5: Too few parameters",
" 6: No user logged in",
" 7: A user is already logged in",
" 8: Invalid password",
" 9: No such user registered",
"10: No such user in UMS.CONFIG",
"11: No msg active",
"12: UMS read error",
"13: System shutting down",
"14: No stemname set",
"15: Name too long",
"16: User timed out",
"17: Out of memory",
"18: Only password of current user available",
"19: File not found"
};
UBYTE KMSRexx = 0;
static STRPTR KMSRexxStr;
static STRPTR KMSRexxVar;
static ULONG KMSRexxRes;
static UBYTE KMSRexxErr;
/*******************************************
* Rexx-"Dispatch"-Funktion *
* -> Ausfuehrung interner Rexx-Befehle *
* Vorsicht!: Bei rekursiven Aufrufen *
* ist diese Prozedur sehr Stack-intensiv! *
*******************************************
* I: RexxMsg, CommandList, Argumente *
* O: --- *
*******************************************/
/// "KMSRexxDisp"
static VOID (*funktion)(struct RexxMsg *, STRPTR, UBYTE, STRPTR *);
static VOID (*readargfunc)(struct RexxMsg *, LONG[]);
VOID KMSRexxDisp(struct RexxMsg *msg, struct rexxCommandList *dat, STRPTR p)
{
KMSRexxStr = NULL;
KMSRexxVar = NULL;
KMSRexxRes = 0;
KMSRexxErr = 0;
if(CheckStack())
{
KMSRexx++;
if (dat->template)
{
LONG rxargv[REXXCMDARGS];
struct RDArgs *rda;
STRPTR parsebuff;
UWORD n;
for(n = 0; n < REXXCMDARGS; n++)
rxargv[n] = NULL;
parsebuff = malloc(strlen(p) + 2);
if (parsebuff)
{
strcpy(parsebuff, p);
strcat(parsebuff, "\n");
rda = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
if (rda)
{
rda->RDA_ExtHelp = NULL;
rda->RDA_Source.CS_Buffer = parsebuff;
rda->RDA_Source.CS_Length = strlen(parsebuff) + 1;
if (rda = ReadArgs(dat->template, rxargv, rda))
{
KMS_LC = GetKMSLC(msg);
/* LocalConfig des Befehlsgebers ermitteln */
/* Ist NULL, wenn Befehl nicht von Client */
readargfunc = dat->userdata;
readargfunc(msg, rxargv);
FreeArgs(rda);
}
else
{
KMSRexxErr = ERR_INVALID_PARAMS;
KMSRexxRes = 20;
}
FreeDosObject(DOS_RDARGS, rda);
}
else
{
KMSRexxErr = ERR_OUT_OF_MEMORY;
KMSRexxRes = 20;
}
free(parsebuff);
}
else
{
KMSRexxErr = ERR_OUT_OF_MEMORY;
KMSRexxRes = 20;
}
}
else
{
STRPTR *argv[MAXCMDARGS];
STRPTR rexxbuff;
UBYTE argc;
rexxbuff = malloc(LEN_REXXBUFF+1);
if (!rexxbuff)
{
KMSRexxErr = ERR_OUT_OF_MEMORY;
KMSRexxRes = 20;
}
else
{
strcpy(rexxbuff, dat->name);
strncat(rexxbuff, p, LEN_REXXBUFF-strlen(rexxbuff));
rexxbuff[LEN_REXXBUFF] = '\0';
argc = 0;
RexxCmdParse(rexxbuff, &argc, argv); /* Kommando tokenisieren */
KMS_LC = GetKMSLC(msg); /* LocalConfig des Befehlsgebers ermitteln */
/* Ist NULL, wenn Befehl nicht von Client */
funktion = dat->userdata;
funktion(msg, p, argc, argv);
RexxCmdParse(NULL, &argc, argv); /* Token freigeben */
free(rexxbuff);
}
}
KMSRexx--;
}
else
{
KMSRexxErr = ERR_OUT_OF_MEMORY;
KMSRexxRes = 20;
}
if(KMSRexxErr)
SetARexxLastError(msg, RexxErrStr[KMSRexxErr]);
else if(KMSRexxVar && KMSRexxStr)
SetRexxVar((struct Message *)msg, KMSRexxVar, KMSRexxStr, (ULONG)strlen(KMSRexxStr));
replyRexxCmd(msg, KMSRexxRes, KMSRexxStr);
if(KMSRexxStr)
free(KMSRexxStr);
if(KMSRexxVar)
free(KMSRexxVar);
}
///
/***************************************
* Rexx-Fehler-RESULT-String *
***************************************
* I: Fehlertext *
* O: --- *
***************************************/
/// "RexxErr"
VOID RexxErr(UWORD errnum)
{
KMSRexxErr = errnum;
KMSRexxRes = 20;
}
///
/***************************************
* Rexx-OK-Standard-RESULT-String *
***************************************
* I: Erfolgstext/-daten, Varname *
* O: --- *
***************************************/
/// "RexxOK"
VOID RexxOK(STRPTR restxt, STRPTR varname)
{
if(restxt)
KMSRexxStr = strdup(restxt);
if(varname)
KMSRexxVar = strdup(varname);
}
///
/***************************************
* Rexx-Kommando "GETKMSGC" *
***************************************
* I: Parameterstring *
* O: --- *
***************************************/
/// "Rexx_GETKMSGC"
/* "" */
VOID Rexx_GETKMSGC(struct RexxMsg *msg, LONG rxargv[])
{
TEXT buff[LEN_NUMBER+1];
sprintf(buff, "%ld", (ULONG)KMSBase);
RexxOK(buff, NULL);
}
///
/***************************************
* Rexx-Kommando "SHUTDOWN" *
***************************************
* I: Parameterstring *
* O: --- *
***************************************/
/// "Rexx_SHUTDOWN"
/* DELAY/K/N,UMS/S */
VOID Rexx_SHUTDOWN(struct RexxMsg *msg, LONG rxargv[])
{
TEXT buff[LEN_NUMBER+15+1];
if (rxargv[0]) /* DELAY/K/N */
{
UWORD offset = *(UWORD *)rxargv[0];
sprintf(buff, "SHUTDOWN DELAY %d", offset);
SendPortCmd(buff);
ShutDown = SHUTDOWN_DELAYED;
}
else if(rxargv[1]) /* UMS/S */
{
SendPortCmd("SHUTDOWN");
ShutDown = SHUTDOWN_IMMED_SYS;
}
else
{
SendPortCmd("SHUTDOWN");
ShutDown = SHUTDOWN_IMMEDIATE;
}
}
///
/***************************************
* Rexx-Kommando "LOCKPORT" *
***************************************
* I: Parameterstring *
* O: --- *
***************************************/
/// "Rexx_LOCKPORT"
/* DELAY/K/N */
VOID Rexx_LOCKPORT(struct RexxMsg *msg, LONG rxargv[])
{
TEXT buff[LEN_NUMBER+15+1];
if (rxargv[0]) /* DELAY/K/N */
{
UWORD offset = *(UWORD *)rxargv[0];
sprintf(buff, "LOCKPORT DELAY %d", offset);
SendPortCmd(buff);
}
else
SendPortCmd("LOCKPORT");
}
///
/***************************************
* Rexx-Kommando "UNLOCKPORT" *
***************************************
* I: Parameterstring *
* O: --- *
***************************************/
/// "Rexx_UNLOCKPORT"
/* "" */
VOID Rexx_UNLOCKPORT(struct RexxMsg *msg, LONG rxargv[])
{
SendPortCmd("UNLOCKPORT");
}
///
/***************************************
* Rexx-Kommando "SAVESYS" *
***************************************
* I: Parameterstring *
* O: --- *
***************************************/
/// "Rexx_SAVESYS"
/* "" */
VOID Rexx_SAVESYS(struct RexxMsg *msg, LONG rxargv[])
{
SaveData();
}
///
/***************************************
* Rexx-Kommando "LOGENTRY" *
***************************************
* I: Parameterstring *
* O: --- *
***************************************/
/// "Rexx_LOGENTRY"
/* TEXT/F */
VOID Rexx_LOGENTRY(struct RexxMsg *msg, LONG rxargv[])
{
FILE *logfile;
TEXT timeinfo[19];
TEXT logline[LEN_MAXLINE+1];
TEXT target[LEN_NUMBER+4+1];
TEXT intext[LEN_LOGLINE+1];
TEXT dosbuff[LEN_DOSPATH+1];
UBYTE loglevel = 9;
if (!rxargv[0]) /* TEXT/F */
{
strcpy(dosbuff, KMSBase->LogDir);
strcat(dosbuff, "KMS.LOG");
logfile = fopen(dosbuff, "a");
if(logfile)
{
fputs("\n", logfile);
fclose(logfile);
}
return;
}
strncpy(intext, (STRPTR)rxargv[0], LEN_LOGLINE);
intext[LEN_LOGLINE] = '\0';
if(*intext >= '1' && *intext <= '9')
loglevel = (UBYTE)(*intext - '0');
if(loglevel > KMSBase->LogLevel)
return;
time_t zeit = time(NULL);
struct tm *zt = localtime(&zeit);
strftime(timeinfo, 18, "%d-%b-%y %H:%M:%S", zt);
if(KMS_LC)
sprintf(logline, "OUT TEXT %%G%%R%1d %s %02d%%O %s%%N", loglevel, timeinfo, KMS_LC->ID, intext+1);
else
sprintf(logline, "OUT TEXT %%G%%R%1d %s --%%O %s%%N", loglevel, timeinfo, intext+1);
TakeMSem(FALSE);
struct KMSNode *member = KMSBase->MemberList.mlh_Head;
while(member->Node.mln_Succ)
{
if(member->LCPtr->OutputLog)
{
sprintf(target, "KMS.%d", member->LCPtr->ID);
sendRexxCmd(logline, NULL, NULL, NULL, NULL, target);
}
member = member->Node.mln_Succ;
}
DropMSem();
/* Log-Datei */
if(KMS_LC)
sprintf(logline, "%1d %s %02d %s\n", loglevel, timeinfo, KMS_LC->ID, intext+1);
else
sprintf(logline, "%1d %s -- %s\n", loglevel, timeinfo, intext+1);
strcpy(dosbuff, KMSBase->LogDir);
strcat(dosbuff, "KMS.LOG");
logfile = fopen(dosbuff, "a");
if(logfile)
{
fprintf(logfile, logline);
fclose(logfile);
}
}
///
/***************************************
* Rexx-Kommando "EXPIRE" *
***************************************
* I: RexxMsg, Parameterstring, Args *
* O: --- *
***************************************/
/// "Rexx_EXPIRE"
/* QUIET/S,RESET/S,UNLISTED/S */
VOID Rexx_EXPIRE(struct RexxMsg *msg, LONG rxargv[])
{
BPTR out = NULL;
TEXT buff[LEN_MAXLINE+1];
TEXT timeinfo[19];
BOOL reset = FALSE;
BOOL unlisted = FALSE;
if(KMS_LC)
out = KMS_LC->OutHandle;
else
out = Output();
if(rxargv[0]) /* QUIET/S */
out = NULL;
if(rxargv[1]) /* RESET/S */
reset = TRUE;
if(rxargv[2]) /* UNLISTED/S */
unlisted = TRUE;
time_t zeit = time(NULL);
struct tm *zt = localtime(&zeit);
strftime(timeinfo, 18, "%d-%b-%y %H:%M:%S", zt);
if(out)
{
sprintf(buff, "%s\r\n", timeinfo);
Write(out, buff, strlen(buff));
}
if(reset)
{
/* Alle Expired-Flags ruecksetzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadGlobal, TRUE,
UMSTAG_SelMask, UMSGSTATF_Expired,
UMSTAG_SelMatch, UMSGSTATF_Expired,
UMSTAG_SelWriteGlobal, TRUE,
UMSTAG_SelUnset, UMSGSTATF_Expired,
TAG_DONE);
}
if(unlisted)
{
if(out)
{
strcpy(buff, "\r\nExpiring unlisted UMS groups...\r\n");
Write(out, buff, strlen(buff));
}
UMSMsgNum msgnum, num;
STRPTR areaname;
/* Alle Local 8 rücksetzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<8),
TAG_DONE);
/* Für alle gelöschten Msgs Local 8 setzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadGlobal, TRUE,
UMSTAG_SelMask, UMSGSTATF_Deleted,
UMSTAG_SelMatch, UMSGSTATF_Deleted,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<8),
TAG_DONE);
/* Solange weitere Nachricht mit nicht gesetztem Local-Flag 8 */
msgnum = 0;
while(msgnum = UMSSearchTags(SysUMSAccount, UMSTAG_SearchLast, msgnum,
UMSTAG_SearchDirection, 1,
UMSTAG_SearchLocal, TRUE,
UMSTAG_SearchMask, (1L<<8),
UMSTAG_SearchMatch, 0,
TAG_DONE))
{
/* Gruppennamen besorgen */
if(ReadUMSMsgTags(SysUMSAccount, UMSTAG_RMsgNum, msgnum,
UMSTAG_RGroup, &areaname,
TAG_DONE))
{
/* In allen Nachrichten der Gruppe Local-Flag 8 setzen */
UMSSelectTags(SysUMSAccount, UMSTAG_WGroup, (LONG)areaname ? (LONG)areaname : (LONG)"",
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<8),
UMSTAG_SelQuick, TRUE,
TAG_DONE);
/* Wenn Echomail-Gruppe */
if(areaname)
{
/* Gefundene Area zum expirieren vormerken */
if(!AreaSearch(areaname))
{
num = UMSSelectTags(SysUMSAccount, UMSTAG_WGroup, (LONG)areaname,
UMSTAG_SelWriteGlobal, TRUE,
UMSTAG_SelSet, UMSGSTATF_Expired,
UMSTAG_SelQuick, TRUE,
TAG_DONE);
if(out)
{
sprintf(buff, "%-73.73s -%4d\r\n", areaname, num);
Write(out, buff, strlen(buff));
}
}
}
}
/* Message freigeben */
FreeUMSMsg(SysUMSAccount, msgnum);
}
}
if(out)
{
strcpy(buff, "\r\nExpiring KMS groups...\r\n");
Write(out, buff, strlen(buff));
}
/* Alle Local 8 und 9 rücksetzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<8)|(1L<<9),
TAG_DONE);
/* Für alle archivierten Msgs Local 8 setzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelMask, UMSUSTATF_Archive,
UMSTAG_SelMatch, UMSUSTATF_Archive,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<8),
TAG_DONE);
/* Für alle gelöschten Msgs Local 9 setzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadGlobal, TRUE,
UMSTAG_SelMask, UMSGSTATF_Deleted,
UMSTAG_SelMatch, UMSGSTATF_Deleted,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<9),
TAG_DONE);
/* Alle Areas durchgehen */
TakeASem(FALSE);
struct AreaNode *apoint = (struct AreaNode *)KMSBase->AreaList.mlh_Head;
while(apoint->Node.mln_Succ)
{
UMSMsgNum count, arch, zaehl;
UMSMsgNum hold = apoint->AreaData.HoldNum;
UMSMsgNum num = 0;
UMSMsgNum del = 0;
/* Alle gesetzten Local 2 rücksetzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadLocal, TRUE,
UMSTAG_SelMask, (1L<<2),
UMSTAG_SelMatch, (1L<<2),
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<2),
TAG_DONE);
/* Alle Nachrichten in aktueller Gruppe mit Local 2 markieren */
count =
UMSSelectTags(SysUMSAccount, UMSTAG_WGroup, apoint->AreaData.MBName,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<2),
UMSTAG_SelQuick, TRUE,
TAG_DONE);
/* Für alle gelöschten Msgs Local 2 wieder löschen */
count -=
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadLocal, TRUE,
UMSTAG_SelMask, (1L<<2)|(1L<<9),
UMSTAG_SelMatch, (1L<<2)|(1L<<9),
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<2),
TAG_DONE);
/* Für alle archivierten Msgs Local 2 wieder löschen */
arch =
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadLocal, TRUE,
UMSTAG_SelMask, (1L<<2)|(1L<<8),
UMSTAG_SelMatch, (1L<<2)|(1L<<8),
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<2),
TAG_DONE);
/* Anzahl maximal zu löschender Nachrichten berechnen */
if(hold > 0 && count - arch > hold)
del = count - arch - hold;
/* Jetzt <del> Nachrichten zum löschen freigeben */
if(del)
{
for(zaehl = 1; zaehl <= del; zaehl++)
{
num =
UMSSearchTags(SysUMSAccount, UMSTAG_SearchLast, num,
UMSTAG_SearchDirection, 1,
UMSTAG_SearchLocal, TRUE,
UMSTAG_SearchMask, (1L<<2),
UMSTAG_SearchMatch, (1L<<2),
TAG_DONE);
if(num)
{
/* Expired-Flag setzen */
UMSSelectTags(SysUMSAccount, UMSTAG_SelMsg, num,
UMSTAG_SelWriteGlobal, TRUE,
UMSTAG_SelSet, UMSGSTATF_Expired,
TAG_DONE);
}
}
}
/* HoldDays auswerten:
date = Sekunden seit 1.1.1978 des heutigen Tages minus HoldDays
(time() liefert Sekunden seit 1.1.1970! -> 8 Jahre abziehen) */
if(apoint->AreaData.HoldDays)
{
LONG date = time(NULL) - (LONG)apoint->AreaData.HoldDays * 24L * 3600L;
/* 8 * 365 Tage + 2 Schalttage zusätzlich abziehen */
date = date - (3600L * 24L * 365L * 8L) - (3600L * 24L * 2L);
if(date < 0)
date = 0;
/* Zurücksetzen Merker-Flag Local 3 */
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadLocal, TRUE,
UMSTAG_SelMask, (1L<<3),
UMSTAG_SelMatch, (1L<<3),
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelUnset, (1L<<3),
TAG_DONE);
/* Local 3 setzen bei allen schon expirierten Msgs */
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadGlobal, TRUE,
UMSTAG_SelMask, UMSGSTATF_Expired,
UMSTAG_SelMatch, UMSGSTATF_Expired,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<3),
TAG_DONE);
/* Local 3 setzen bei allen Msgs, die jünger als date sind */
UMSSelectTags(SysUMSAccount, UMSTAG_SelDate, date,
UMSTAG_SelWriteLocal, TRUE,
UMSTAG_SelSet, (1L<<3),
TAG_DONE);
/* Bei allen älteren Msgs in akt. Brett Expired-Flag setzen */
del +=
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadLocal, TRUE,
UMSTAG_SelMask, (1L<<2)|(1L<<3),
UMSTAG_SelMatch, (1L<<2),
UMSTAG_SelWriteGlobal, TRUE,
UMSTAG_SelSet, UMSGSTATF_Expired,
TAG_DONE);
}
if(out)
{
sprintf(buff, "%-30.30s (Num:%4d/Days:%3d/Curr:%4d/Prot:%4d) -> -%4d\r\n", strlen(apoint->AreaData.MBName) ? apoint->AreaData.MBName : (STRPTR)"-Mail-", apoint->AreaData.HoldNum, apoint->AreaData.HoldDays, count, arch, del);
Write(out, buff, strlen(buff));
}
/* Weiter mit nächstem Brett */
apoint = apoint->Node.mln_Succ;
}
DropASem();
UMSMsgNum sum =
UMSSelectTags(SysUMSAccount, UMSTAG_SelReadGlobal, TRUE,
UMSTAG_SelMask, UMSGSTATF_Expired,
UMSTAG_SelMatch, UMSGSTATF_Expired,
TAG_DONE);
if(out)
{
sprintf(buff, "%79s\r\n%74s%5ld\r\n\r\n", "=====", " => ", sum);
Write(out, buff, strlen(buff));
}
sprintf(buff, "%ld", sum);
RexxOK(buff, NULL);
}
///
/***************************************
* Rexx-Kommando "REFRESH" *
***************************************
* I: RexxMsg, Parameterstring, Args *
* O: --- *
***************************************/
/// "Rexx_REFRESH"
/* SYSTEM/S,ALL/S,UMSGLOBAL/S */
VOID Rexx_REFRESH(struct RexxMsg *msg, LONG rxargv[])
{
BOOL system = FALSE;
if(rxargv[0]) /* SYSTEM/S */
system = TRUE;
else if(rxargv[1]) /* ALL/S */
system = TRUE;
else if(rxargv[2]) /* UMSGLOBAL/S */
SendPortCmd("REFRESH UMS");
if(system)
{
// Systemdaten neu einlesen
TEXT dos[LEN_DOSPATH+1];
TEXT buff[LEN_NUMBER+LEN_ACCBITNAME+2];
UWORD n;
FILE *datei;
strcpy(dos, KMSBase->DatDir);
strcat(dos, "KMS_SYSTEM.DAT");
if(datei = fopen(dos, "r"))
{
fgets(buff, LEN_NUMBER+2, datei);
KMSBase->SystemStartups = atol(buff) + 1;
for(n = 0; n < 32; n++)
{
*buff = '\0';
if(fgets(buff, LEN_ACCBITNAME+2, datei))
buff[strlen(buff)-1] = '\0';
if(!strlen(buff))
sprintf(KMSBase->AccBitNames[n], "[Bit#%02d]", n+1);
else
strcpy(KMSBase->AccBitNames[n], buff);
}
fclose(datei);
}
else
{
KMSBase->SystemStartups = 1;
for(n = 0; n < 32; n++)
sprintf(KMSBase->AccBitNames[n], "[Bit#%02d]", n+1);
}
}
}
///
/************************************
* Rexx-Msg an alle Ports *
************************************
* I: Rexx-Cmd *
* O: --- *
************************************/
/// "SendPortCmd"
VOID SendPortCmd(STRPTR command)
{
TEXT target[LEN_NUMBER+4+1];
TakeMSem(FALSE);
struct KMSNode *member = KMSBase->MemberList.mlh_Head;
while(member->Node.mln_Succ)
{
sprintf(target, "KMS.%d", member->LCPtr->ID);
sendRexxCmd(command, NULL, NULL, NULL, NULL, target);
member = member->Node.mln_Succ;
}
DropMSem();
}
///
/***************************************
* REXX-Kommando-Parser *
***************************************
* I: STRPTR parsepuff, UBYTE *argc, *
* I: STRPTR argv[] *
* O: --- *
***************************************/
/// "RexxCmdParse"
VOID RexxCmdParse(STRPTR parsepuff, UBYTE *argc, STRPTR argv[])
{
UWORD inzeig = 0;
UWORD anfang = 0;
TEXT c;
if(*argc > 0)
{
/* Token freigeben */
for(inzeig = 0; inzeig < *argc; inzeig++)
free(argv[inzeig]);
return;
}
if(!parsepuff)
return;
/* Hier geht die Parserei los */
*argc = 0;
while(parsepuff[inzeig] == ' ' || parsepuff[inzeig] == ',')
inzeig++;
do
{
if(parsepuff[inzeig] == '"')
{
inzeig++;
anfang = inzeig;
while((c = parsepuff[inzeig]) != '"' && c != '\0')
inzeig++;
}
else if(parsepuff[inzeig] == '\'')
{
inzeig++;
anfang = inzeig;
while((c = parsepuff[inzeig]) != '\'' && c != '\0')
inzeig++;
}
else if(*argc == 0 && parsepuff[inzeig] == '@')
{
anfang = inzeig;
inzeig++;
}
else
{
anfang = inzeig;
while((c = parsepuff[inzeig]) != ' ' && c != ',' && c != '\0')
inzeig++;
}
if(inzeig-anfang >= 0)
{
argv[*argc] = (STRPTR)malloc(inzeig-anfang+1);
if(!argv[*argc])
{
RexxErr(ERR_OUT_OF_MEMORY);
*argc = 0;
c = '\0';
}
else
{
strncpy(argv[*argc], &parsepuff[anfang], inzeig-anfang);
argv[*argc][inzeig-anfang] = '\0';
(*argc)++;
if(c == '"' || c == '\'')
inzeig++;
while((c = parsepuff[inzeig]) == ' ' || c == ',')
inzeig++;
}
}
} while(c != '\0' && *argc < MAXCMDARGS);
}
///
/***************************************
* Stack-Prüfung *
***************************************
* I: --- *
* O: TRUE: OK, FALSE: Out Of Memory *
***************************************/
/// CheckStack
BOOL CheckStack(VOID)
{
struct Task *mytask = FindTask(NULL);
if(mytask->tc_SPReg - mytask->tc_SPLower > 1024)
return TRUE;
else
return FALSE;
}
///
/***************************************
* LocalConfig des Befehlsgebers holen *
***************************************
* I: struct RexxMsg * *
* O: struct LocalConfig * *
***************************************/
/// GetKMSLC
struct LocalConfig *GetKMSLC(struct RexxMsg *msg)
{
if(!msg->rm_Args[2])
return NULL;
UWORD id = (UWORD)msg->rm_Args[2];
TakeMSem(FALSE);
struct KMSNode *member = KMSBase->MemberList.mlh_Head;
while(member->Node.mln_Succ)
{
if(member->LCPtr->ID == id)
{
DropMSem();
return member->LCPtr;
}
member = member->Node.mln_Succ;
}
DropMSem();
return NULL;
}
///
/*******************************************
* UMS-MsgBase-Namen global suchen *
*******************************************
* I: gesuchte Area *
* O: AreaNode *
*******************************************/
/// AreaSearch
struct AreaNode *AreaSearch(STRPTR name)
{
struct AreaNode *apoint;
apoint = (struct AreaNode *)KMSBase->AreaList.mlh_Head;
while(apoint->Node.mln_Succ)
{
if(!stricmp(name, apoint->AreaData.MBName))
return apoint;
apoint = apoint->Node.mln_Succ;
}
return NULL;
}
///
/*******************************************
* Member-Semaphore locken *
*******************************************
* I: Exklusiv? *
* O: --- *
*******************************************/
/// TakeMSem
VOID TakeMSem(BOOL exclusive)
{
if(exclusive)
ObtainSemaphore(&KMSBase->SaveSem);
else
ObtainSemaphoreShared(&KMSBase->SaveSem);
}
///
/*******************************************
* Member-Semaphore freigeben *
*******************************************
* I: --- *
* O: --- *
*******************************************/
/// DropMSem
VOID DropMSem(VOID)
{
ReleaseSemaphore(&KMSBase->SaveSem);
}
///
/*******************************************
* Area-Semaphore locken *
*******************************************
* I: Exklusiv? *
* O: --- *
*******************************************/
/// TakeASem
VOID TakeASem(BOOL exclusive)
{
if(exclusive)
ObtainSemaphore(&KMSBase->AreaSem);
else
ObtainSemaphoreShared(&KMSBase->AreaSem);
}
///
/*******************************************
* Area-Semaphore freigeben *
*******************************************
* I: --- *
* O: --- *
*******************************************/
/// DropASem
VOID DropASem(VOID)
{
ReleaseSemaphore(&KMSBase->AreaSem);
}
///